using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace IUPUI.StellarResults.Client.UIElements
{
	/// <summary>
	/// A visual representation of an <see cref="AstronomicalTimer"/>.
	/// </summary>
	public partial class AstronomicalTimerControl : UserControl
	{
		#region Private Properties
		#endregion Private Properties

		#region Public Properties
		/// <summary>
		/// Gets the astronomical timer.
		/// </summary>
		/// <value>The astronomical timer.</value>
		[Browsable(false)]
		public AstronomicalTimer AstronomicalTimer
		{
			get
			{
				return m_AstronomicalTimer;
			}
		}
		#endregion Public Properties

		#region Constructors
		/// <summary>
		/// Initializes a new instance of the <see cref="AstronomicalTimerControl"/> class.
		/// </summary>
		public AstronomicalTimerControl()
		{
			InitializeComponent();

			if (!this.DesignMode)
			{
				// Initialize astronomical timer
				m_AstronomicalTimer.CurrentDateTimeChanged += 
					new EventHandler<ININ.EventArgs<DateTime>>(m_AstronomicalTimer_CurrentDateTimeChanged);
				OnCurrentDateTimeChanged();
				m_AstronomicalTimer.EnabledChanged += 
					new EventHandler<ININ.EventArgs<bool>>(m_AstronomicalTimer_EnabledChanged);
				OnEnabledChanged();
				OnSpeedChanged();
			}
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="AstronomicalTimerControl"/> class.
		/// </summary>
		/// <param name="container">The container.</param>
		public AstronomicalTimerControl(
			IContainer container) : this()
		{
			container.Add(this);
		}
		#endregion Constructors

		/// <summary>
		/// Handles the EnabledChanged event of the m_AstronomicalTimer control.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="ININ.EventArgs&lt;System.Boolean&gt;"/> instance containing the event data.</param>
		private void m_AstronomicalTimer_EnabledChanged(object sender, ININ.EventArgs<bool> e)
		{
			if (this.InvokeRequired)
			{
				// Invoke on UI thread
				this.Invoke(
					new EventHandler<ININ.EventArgs<bool>>(m_AstronomicalTimer_EnabledChanged), 
					sender, 
					e);
			}
			else
			{
				OnEnabledChanged();
			}
		}

		/// <summary>
		/// Handles the TimerElapsed event of the m_AstronomicalTimer control.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		private void m_AstronomicalTimer_CurrentDateTimeChanged(object sender, ININ.EventArgs<DateTime> e)
		{
			try
			{
				if (!this.IsDisposed && !m_AstronomicalTimer.IsDisposed)
				{
					if (this.InvokeRequired)
					{
						// Invoke on UI thread
						this.Invoke(
							new EventHandler<ININ.EventArgs<DateTime>>(m_AstronomicalTimer_CurrentDateTimeChanged),
							sender,
							e);
					}
					else
					{
						OnCurrentDateTimeChanged();
					}
				}
			}
			catch
			{
				//ignore
			}
		}

		/// <summary>
		/// Called when [current date time changed].
		/// </summary>
		private void OnCurrentDateTimeChanged()
		{
			if (m_AstronomicalTimer.CurrentDateTimeUTC != DateTime.MinValue)
			{
				m_CurrentDateTimePicker.Text =
					m_AstronomicalTimer.CurrentDateTimeUTC.ToLocalTime().ToString();
			}
		}

		/// <summary>
		/// Called when [enabled changed].
		/// </summary>
		private void OnEnabledChanged()
		{
			//m_CurrentDateTimePicker.Enabled = !m_AstronomicalTimer.Enabled;
			m_StartButton.Enabled = !m_AstronomicalTimer.Enabled;
			m_StopButton.Enabled = m_AstronomicalTimer.Enabled;
		}

		/// <summary>
		/// Called when [speed changed].
		/// </summary>
		private void OnSpeedChanged()
		{
			switch (m_SpeedTrackBar.Value)
			{
				case 0:
					m_ToolTip.SetToolTip(m_SpeedTrackBar, Properties.Resources.AstronomicalTimerSpeedOneSecond);
					m_AstronomicalTimer.Speed.Unit = ININ.DateTimeUnit.Seconds;
					m_AstronomicalTimer.Speed.Value = 1;
					break;
				case 1:
					m_ToolTip.SetToolTip(m_SpeedTrackBar, String.Format(Properties.Resources.AstronomicalTimerSpeedSeconds, "30"));
					m_AstronomicalTimer.Speed.Unit = ININ.DateTimeUnit.Seconds;
					m_AstronomicalTimer.Speed.Value = 30;
					break;
				case 2:
					m_ToolTip.SetToolTip(m_SpeedTrackBar, Properties.Resources.AstronomicalTimerSpeedOneMinute);
					m_AstronomicalTimer.Speed.Unit = ININ.DateTimeUnit.Minutes;
					m_AstronomicalTimer.Speed.Value = 1;
					break;
				case 3:
					m_ToolTip.SetToolTip(m_SpeedTrackBar, String.Format(Properties.Resources.AstronomicalTimerSpeedMinutes, "5"));
					m_AstronomicalTimer.Speed.Unit = ININ.DateTimeUnit.Minutes;
					m_AstronomicalTimer.Speed.Value = 5;
					break;
				case 4:
					m_ToolTip.SetToolTip(m_SpeedTrackBar, String.Format(Properties.Resources.AstronomicalTimerSpeedMinutes, "15"));
					m_AstronomicalTimer.Speed.Unit = ININ.DateTimeUnit.Minutes;
					m_AstronomicalTimer.Speed.Value = 15;
					break;
				case 5:
					m_ToolTip.SetToolTip(m_SpeedTrackBar, String.Format(Properties.Resources.AstronomicalTimerSpeedMinutes, "30"));
					m_AstronomicalTimer.Speed.Unit = ININ.DateTimeUnit.Minutes;
					m_AstronomicalTimer.Speed.Value = 30;
					break;
				case 6:
					m_ToolTip.SetToolTip(m_SpeedTrackBar, String.Format(Properties.Resources.AstronomicalTimerSpeedMinutes, "45"));
					m_AstronomicalTimer.Speed.Unit = ININ.DateTimeUnit.Minutes;
					m_AstronomicalTimer.Speed.Value = 45;
					break;
				case 7:
					m_ToolTip.SetToolTip(m_SpeedTrackBar, String.Format(Properties.Resources.AstronomicalTimerSpeedMinutes, "60"));
					m_AstronomicalTimer.Speed.Unit = ININ.DateTimeUnit.Minutes;
					m_AstronomicalTimer.Speed.Value = 60;
					break;
				case 8:
					m_ToolTip.SetToolTip(m_SpeedTrackBar, String.Format(Properties.Resources.AstronomicalTimerSpeedMinutes, "75"));
					m_AstronomicalTimer.Speed.Unit = ININ.DateTimeUnit.Minutes;
					m_AstronomicalTimer.Speed.Value = 75;
					break;
				case 9:
					m_ToolTip.SetToolTip(m_SpeedTrackBar, String.Format(Properties.Resources.AstronomicalTimerSpeedMinutes, "90"));
					m_AstronomicalTimer.Speed.Unit = ININ.DateTimeUnit.Minutes;
					m_AstronomicalTimer.Speed.Value = 90;
					break;
			}
		}

		/// <summary>
		/// Handles the Click event of the m_StopButton control.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		private void m_StopButton_Click(object sender, EventArgs e)
		{
			m_AstronomicalTimer.Stop();
		}

		/// <summary>
		/// Handles the Click event of the m_StartButton control.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		private void m_StartButton_Click(object sender, EventArgs e)
		{
			m_AstronomicalTimer.Start();
		}

		/// <summary>
		/// Handles the Scroll event of the m_SpeedTrackBar control.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		private void m_SpeedTrackBar_Scroll(object sender, EventArgs e)
		{
			OnSpeedChanged();
		}

		/// <summary>
		/// Handles the ValueChanged event of the m_CurrentDateTimePicker control.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		private void m_CurrentDateTimePicker_ValueChanged(object sender, EventArgs e)
		{
			if (m_AstronomicalTimer.CurrentDateTimeUTC !=
				m_CurrentDateTimePicker.Value.ToUniversalTime())
			{
				m_AstronomicalTimer.CurrentDateTimeUTC =
				m_CurrentDateTimePicker.Value.ToUniversalTime();
			}
		}
	}
}
